package cn.edu.gdgm.system.config;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
import cn.fightingguys.security.web.wechat.auth.InMemoryWeChatUserDetailsManager;
import cn.fightingguys.security.web.wechat.config.WeChatMiniProgramSecurityConfiguration;
import cn.fightingguys.security.web.wechat.config.WeChatMiniProgramSecurityConfigurer;
import cn.fightingguys.security.web.wechat.config.WeChatMiniProgramSecurityJwtSettings;
import cn.fightingguys.security.web.wechat.config.WeChatMiniProgramSecurityProviderSettings;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.provisioning.UserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

import java.security.Key;


@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Import(WeChatMiniProgramSecurityConfiguration.class)
@ConfigurationProperties(prefix = "wechat.miniprogram")
public class SpringSecurityConfig {

    private String appId;

    private String appSecret;

    @Bean
    public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .apply(new WeChatMiniProgramSecurityConfigurer<>());
        return http.build();
    }

    /*
     * 例子使用的临时 Jwt 私钥，仅在当前进程有效，Springboot程序关闭将失去私钥
     */
    private final static Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);

    @Bean
    public WeChatMiniProgramSecurityProviderSettings weChatMiniProgramSecurityProviderSetting() {
        /*
         *  在开发设置页面查看AppID和AppSecret
         *  https://mp.weixin.qq.com/
         */
        return new WeChatMiniProgramSecurityProviderSettings()
                .appId(appId)       // 微信小程序 AppId
                .secret(appSecret)  // 微信小程序 Secret
                .endpoint("/user/wxLogin");// 登录接口

    }

    @Bean
    public WeChatMiniProgramSecurityJwtSettings weChatMiniProgramSecurityJwtSettings() {
        return new WeChatMiniProgramSecurityJwtSettings()
                .issuer("https://fightingguys.cn/")  // 设置 Jwt 发布者信息
                .privateKey(key);               // 设置 Jwt 签名私钥
    }


    @Bean
    public UserDetailsManager userDetailsManager() {
        /* 微信用户信息服务，用户可自定义信息，可实现数据库存储用户信息
         * 继承 InMemoryWeChatUserDetailsManager，否则控制器无法获取用户信息
         * 不用也行，默认的 User 类也可以，Username是OpenId、Password就不用
         * 控制器就转成自己写的 UserDetails 就可以
         */
        return new InMemoryWeChatUserDetailsManager();
    }

    @Bean
    public WxMaService wxMaService() {
        WxMaService wxMaService = new WxMaServiceImpl();
        WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
        config.setAppid(appId);
        config.setSecret(appSecret);
        wxMaService.setWxMaConfig(config);
        return wxMaService;
    }

    public void setAppId(String appId) {
        this.appId = appId;
    }

    public void setAppSecret(String appSecret) {
        this.appSecret = appSecret;
    }
}

